package test.task.fun.service;

import java.util.ArrayList;
import java.util.List;

import test.task.fun.model.Goods;
import test.task.fun.model.GoodsPosition;
import test.task.fun.serialize.Serializer;
import test.task.fun.serialize.SerializerImpl;
import android.content.Context;
import android.os.Handler;
import android.os.Message;

public class GoodsStore {

	private final List<GoodsPosition> goodsPositions = new ArrayList<GoodsPosition>();
	private static GoodsStore instance;

	private final Serializer serializer = new SerializerImpl();
	private final PreferenceAdapter preferenceAdapter;

	private Handler onGoodsCreateHandler;
	private Handler onGoodsQuantityChangedHandler;
	private Handler onGoodsRemovedHandler;

	public static GoodsStore getInstance(Context context) {
		if (instance == null) {
			instance = new GoodsStore(context);
		}

		return instance;

	}

	private GoodsStore(Context context) {
		preferenceAdapter = new PreferenceAdapter(context);

	}

	public void addGoods(final Goods goods) {
		GoodsPosition goodsPosition = getGoodsPosition(goods);

		if (goodsPosition != null) {
			goodsPosition.setQuantity(goodsPosition.getQuantity() + 1);
			nofityGoodsQuantityChange(goodsPosition);
			persistState();
			return;
		}
		goodsPosition = new GoodsPosition();
		goodsPosition.setGoods(goods);
		goodsPosition.setQuantity(1);

		addGoodsToList(goodsPosition);

		Message mes = onGoodsCreateHandler.obtainMessage();
		mes.obj = goods;
		onGoodsCreateHandler.sendMessage(mes);

		persistState();

	}

	public void buyGoods(Goods goods) {
		GoodsPosition goodsPosition = getGoodsPosition(goods);

		if (goodsPosition != null) {
			if (goodsPosition.getQuantity() <= 1) {
				removeGoodsFromList(goodsPosition);
				notifyOnGoodsRemoved(goods);
			} else {
				goodsPosition.setQuantity(goodsPosition.getQuantity() - 1);
				// actionListener.onGoodsQuantityChanged(goodsPosition);
				nofityGoodsQuantityChange(goodsPosition);

			}

			persistState();
			return;

		}

		notifyOnGoodsRemoved(goods);

		persistState();
	}

	/**
	 * Синхронизируем доступ к коллекции для GUI потока и потоков
	 * 
	 * @param goodsPosition
	 */
	private synchronized void addGoodsToList(GoodsPosition goodsPosition) {
		goodsPositions.add(goodsPosition);
	}

	private synchronized void removeGoodsFromList(GoodsPosition goodsPosition) {
		goodsPositions.remove(goodsPosition);
	}

	private synchronized List<GoodsPosition> getGoodsPositions() {
		List<GoodsPosition> goodsPositions = new ArrayList<GoodsPosition>();
		goodsPositions.addAll(this.goodsPositions);
		return goodsPositions;

	}

	private synchronized void setGoodsPositions(List<GoodsPosition> positions) {
		this.goodsPositions.clear();
		this.goodsPositions.addAll(positions);
	}

	private void notifyOnGoodsRemoved(Goods goods) {
		Message mes = onGoodsCreateHandler.obtainMessage();
		mes.obj = goods;
		onGoodsRemovedHandler.sendMessage(mes);
	}

	private void nofityGoodsQuantityChange(GoodsPosition goodsPosition) {
		Message mes = onGoodsCreateHandler.obtainMessage();
		mes.obj = goodsPosition;
		onGoodsQuantityChangedHandler.sendMessage(mes);
	}

	public void loadGoodsFromStorage(final Handler callBackHandler) {
		new Thread() {

			@Override
			public void run() {
				List<GoodsPosition> positions;
				String string = preferenceAdapter.getString();
				if (string == null) {
					positions = new ArrayList<GoodsPosition>();
				} else {
					positions = serializer.deSerialize(string);
				}

				setGoodsPositions(positions);

				Message msg = callBackHandler.obtainMessage();
				msg.obj = positions;
				callBackHandler.sendMessage(msg);

			}

		}.start();

	}

	public GoodsPosition getGoodsPosition(Goods goods) {
		for (GoodsPosition goodsPosition : getGoodsPositions()) {
			if (goodsPosition.getGoods().equals(goods)) {
				return goodsPosition;
			}
		}
		return null;
	}

	/**
	 * Делаем отдельным потоком, чтобы интерфейс не ждал эту операцию
	 */
	private void persistState() {
		new Thread() {
			@Override
			public void run() {
				String string = serializer.servialize(getGoodsPositions());
				preferenceAdapter.saveString(string);
			}

		}.start();

	}

	public void setOnGoodsCreateHandler(Handler onGoodsCreateHandler) {
		this.onGoodsCreateHandler = onGoodsCreateHandler;
	}

	public void setOnGoodsQuantityChangedHandler(Handler onGoodsQuantityChangedHandler) {
		this.onGoodsQuantityChangedHandler = onGoodsQuantityChangedHandler;
	}

	public void setOnGoodsRemovedHandler(Handler onGoodsRemovedHandler) {
		this.onGoodsRemovedHandler = onGoodsRemovedHandler;
	}

}
